package com.ruoyi.project.manhua.name.service.impl;

import java.util.*;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.framework.qiniu.QiNiuYunUtils;
import com.ruoyi.framework.redis.RedisKey;
import com.ruoyi.framework.redis.RedisUtils;
import com.ruoyi.project.manhua.chapter.domain.MhChapter;
import com.ruoyi.project.manhua.chapter.service.IMhChapterService;
import com.ruoyi.project.manhua.mistake.service.IMhClimbMistakeService;
import com.ruoyi.project.manhua.name.domain.MhName;
import com.ruoyi.project.manhua.name.service.IMhNameService;
import com.ruoyi.project.manhua.newXml.MhNameNewMapper;
import com.ruoyi.project.manhua.page.service.IMhPageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.common.utils.text.Convert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;


/**
 * 漫画名称 Service业务层处理
 *
 * @author yuan
 * @date 2021-01-12
 */
@Service
public class MhNameServiceImpl implements IMhNameService {

    @Autowired
    private MhNameNewMapper nameNewMapper;

    @Autowired
    private IMhChapterService mhChapterService;

    @Autowired
    private IMhPageService mhPageService;

    @Autowired
    private QiNiuYunUtils qiNiuYunUtils;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private IMhClimbMistakeService mhClimbMistakeService;


    /*启用redis开关*/
    @Value("${spring.redis.enabled}")
    private boolean enabled;


    /**
     * 使用redis查询单条漫画数据
     *
     * @param id 漫画名称 ID
     * @return 漫画名称
     */
    @Override
    public MhName selectMhNameById(Long id) {
        MhName mhName = null;

        /*是否开启redis*/
        if (enabled) {

            mhName = (MhName) redisUtils.get(RedisKey.mhName.name_id.getKey() + id);

            if (ObjectUtils.isEmpty(mhName)) {

                synchronized (this) {

                    mhName = (MhName) redisUtils.get(RedisKey.mhName.name_id.getKey() + id);
                    /*还等于null 去数据库中查找*/
                    if (ObjectUtils.isEmpty(mhName)) {

                        mhName = nameNewMapper.selectMhNameById(id);

                        mhName.setTheCover(Constants.getEncoder(qiNiuYunUtils.getUrlImg(mhName.getTheCover())));

                        /*添加redis数据*/
                        redisUtils.set(RedisKey.mhName.name_id.getKey() + id, mhName, RedisKey.time);

                    }
                }
            }

        } else {
            /*如果redis没有开启走数据库*/
            mhName = nameNewMapper.selectMhNameById(id);
            mhName.setTheCover(Constants.getEncoder(qiNiuYunUtils.getUrlImg(mhName.getTheCover())));
        }

        return mhName;

    }

    /**
     * 查询漫画名称 列表
     *
     * @param mhName 漫画名称
     * @return 漫画名称
     */
    @Override
    public List<MhName> selectMhNameList(MhName mhName) {
        return nameNewMapper.selectMhNameList(mhName);
    }

    /**
     * 新增漫画名称
     *
     * @param mhName 漫画名称
     * @return 结果
     */
    @Override
    public int insertMhName(MhName mhName, MultipartFile theCovers) {
        /*创建时间*/
        mhName.setCreateTime(DateUtils.getNowDate());
        /*修改时间*/
        mhName.setUpdateTime(DateUtils.getNowDate());
        //mhName.getTypeName()值类型：100,热血 id：类型名称
        mhName.setTypeId(Long.valueOf(mhName.getTypeName().split(",")[0]));
        /*类型名称*/
        mhName.setTypeName(mhName.getTypeName().split(",")[1]);

        System.err.println("=============================");
        System.err.println(mhName.getCountriesName());
        /*漫画国家id*/
        mhName.setCountriesId(Long.valueOf(mhName.getCountriesName().split(",")[0]));
        /*漫画国名称*/
        mhName.setCountriesName(mhName.getCountriesName().split(",")[1]);
        //创建者
        mhName.setCreateBy(ShiroUtils.getLoginName());
        /*阅读数量*/
        mhName.setReading(Constants.IntegerStatusUtils.one);
        /*收藏*/
        mhName.setCollect(Constants.IntegerStatusUtils.one);
        /*评论*/
        mhName.setComment(Constants.IntegerStatusUtils.zero);
        /*喜欢数量*/
        mhName.setFond(Constants.IntegerStatusUtils.one);
        /*点赞*/
        mhName.setGiveLike(Constants.IntegerStatusUtils.one);

        /*图片不等于空*/
        if (!theCovers.isEmpty()) {
            /*文件原始名*/
            String originalFilename = theCovers.getOriginalFilename();
            /*截取后缀名*/
            String queen = originalFilename.substring(originalFilename.lastIndexOf("."));
            /*文件名*/
            String newName = UUID.randomUUID() + queen;
            /*返回状态*/
            String returnState = qiNiuYunUtils.scyGet(theCovers, newName);
            /*文件名*/
            mhName.setTheCover(qiNiuSwitch(returnState));

        }

        int i = nameNewMapper.insertMhName(mhName);

        /*存放 添加数据的id*/
        Long maxId = null;

        if (i > Constants.IntegerStatusUtils.zero) {
            MhName user = new MhName();
            user.setName(mhName.getName());
            /*获取刚加入的数据*/
            List<MhName> mhNames = nameNewMapper.selectMhNameList(user);

            maxId = mhNames.get(0).getId();

            /*如果 list 大于1 搜索出了两个 ，找出里面最大的那个*/
            if (mhNames.size() >= Constants.IntegerStatusUtils.one) {
                /*stream 流找出最大值*/
                maxId = mhNames.stream().map((e) -> e.getId()).max(Long::compareTo).get();
            }
            /*添加 id 数据*/
            mhName.setId(maxId);
        } else {
            throw new BusinessException("插入数据库失败...");
        }

        /*加密链接*/
        mhName.setTheCover(Constants.getEncoder(qiNiuYunUtils.getUrlImg(mhName.getTheCover())));

        /*放入redis缓存 */
        if (enabled) {
            updateRedis(mhName);
        }

        return i;
    }


    /**
     * 更换封面
     *
     * @param id
     * @param theCovers
     * @return
     */
    @Override
    public int tuPian(Long id, MultipartFile theCovers) {

        /*获取 原始图片名字*/
        MhName mhName = nameNewMapper.selectMhNameById(id);

        /*删除原始图片*/
        if (StringUtils.isNotEmpty(mhName.getTheCover())) {
            Integer delete = qiNiuYunUtils.getDelete(mhName.getTheCover());
            if (delete != 200) {
                throw new BusinessException("删除失败七牛云图片");
            }
        }

        /*文件原始名*/
        String originalFilename = theCovers.getOriginalFilename();
        /*截取后缀名*/
        String queen = originalFilename.substring(originalFilename.lastIndexOf("."));
        /*文件名*/
        String newName = UUID.randomUUID() + queen;
        /*返回状态*/
        String returnState = qiNiuYunUtils.scyGet(theCovers, newName);
        MhName mhName1 = new MhName();
        mhName1.setId(id);
        /*文件名*/
        mhName1.setTheCover(qiNiuSwitch(returnState));

        int i = nameNewMapper.updateMhName(mhName1);

        mhName.setTheCover(Constants.getEncoder(
                qiNiuYunUtils.getUrlImg(
                        mhName1.getTheCover())));

        /*放入redis缓存 */
        if (enabled) {
            updateRedis(mhName);
        }

        return i;
    }


    private boolean updateRedis(MhName mhName) {

        /*放入redis设置过期时间  添加缓存 数据 单个数据*/
        boolean set = redisUtils.set(RedisKey.mhName.name_id.getKey() + mhName.getId(), mhName, RedisKey.time);

        /*更新不成功删除 这个key*/
        if (!set) {
            redisUtils.del(RedisKey.mhName.name_id.getKey() + mhName.getId());
        }

        /*删除 漫画所有数据 list类型*/
        redisUtils.del(RedisKey.mhName.name_all.getKey());

        return true;
    }

    /**
     * 按照阅读量升序分页查询 前十
     *
     * @return
     */
    @Override
    public List<MhName> getQianWu() {
        return nameNewMapper.selectLimit(Constants.IntegerStatusUtils.zero, 10);
    }

    /**
     * 获取redis 储存漫画表 list 所有数据
     *
     * @return
     */
    @Override
    public List<MhName> getRedisListAll() {

        List<Object> list = redisUtils.lGet(RedisKey.mhName.name_all.getKey(), 0, -1);

        List<MhName> lists = null;
        /*redis 是否开启*/
        if (enabled) {
            /*如果等于空*/
            if (CollectionUtils.isEmpty(list)) {

                synchronized (this) {
                    list = redisUtils.lGet(RedisKey.mhName.name_all.getKey(), 0, -1);
                    /*还等于null 去数据库中获取数据*/
                    if (CollectionUtils.isEmpty(list)) {
                        /*去数据库中获取数据*/
                        lists = nameNewMapper.selectMhNameList(null);
                        /*数据库中不等于null 添加在redis中*/
                        if (!CollectionUtils.isEmpty(lists)) {
                            final boolean[] b = {true};
                            lists.forEach((e) -> {
                                e.setTheCover(Constants.getEncoder(qiNiuYunUtils.getUrlImg(e.getTheCover())));
                                /*添加*/
                                b[0] = redisUtils.lSet(RedisKey.mhName.name_all.getKey(), JSON.toJSONString(e), RedisKey.time);
                            });
                            if (!b[0]) {
                                /*不成功删除这个key*/
                                redisUtils.del(RedisKey.mhName.name_all.getKey());
                            }
                        }
                    }
                }
            }
        } else {
            /*如果没有开启redis 数据库中获取*/
            lists = nameNewMapper.selectMhNameList(null);
        }
        /*转换类型*/
        if (CollectionUtils.isEmpty(lists)) {
            lists = new ArrayList<>();
            for (Object e : list) {
                MhName mhName = JSON.parseObject(e.toString(), MhName.class);
                lists.add(mhName);
            }
        }
        return lists;
    }


    /**
     * 修改漫画名称
     * @param mhName 漫画名称
     * @return 结果
     */
    @Override
    public int updateMhName(MhName mhName) {

        mhName.setUpdateTime(DateUtils.getNowDate());
        /*更新者*/
        mhName.setUpdateBy(ShiroUtils.getLoginName());

        /*mhName.getDelFlag() 不等于null证明是要修改 漫画状态*/
        if (mhName.getDelFlag() == null) {

            //mhName.getTypeName()值类型：100,热血 id：类型名称
            if (StringUtils.isNotEmpty(mhName.getTypeName())) {
                mhName.setTypeId(Long.valueOf(mhName.getTypeName().split(",")[0]));

                mhName.setTypeName(mhName.getTypeName().split(",")[1]);

            }

            if (StringUtils.isNotEmpty(mhName.getCountriesName())) {
                /*漫画国家id*/
                mhName.setCountriesId(Long.valueOf(mhName.getCountriesName().split(",")[0]));
                /*漫画国名称*/
                mhName.setCountriesName(mhName.getCountriesName().split(",")[1]);
            }
        }

        /*放入redis缓存 */
        if (enabled) {
            updateRedis(mhName);
        }

        return nameNewMapper.updateMhName(mhName);
    }

    /**
     * 删除漫画名称 对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteMhNameByIds(String ids) {
        String[] array = Convert.toStrArray(ids);
        Arrays.stream(array).forEach((e) -> this.deleteMhNameById(Long.valueOf(e)));
        return 1;
        //return nameNewMapper.deleteMhNameByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除漫画名称 信息
     *
     * @param id 漫画名称 ID
     * @return 结果
     */
    @Override
    public int deleteMhNameById(Long id) {

        List<MhChapter> mhChapters = mhChapterService.selectMhChapterList(new MhChapter(id));

        mhChapters.forEach((e) -> {
            mhChapterService.deleteMhChapterById(e.getId());
        });
        return nameNewMapper.deleteMhNameById(id);
    }

    /**
     * 去重查找作者
     *
     * @return
     */
    @Override
    public List<String> selectDistinct() {
        return nameNewMapper.selectDistinct();
    }

    /**
     * 七牛云异常
     *
     * @param returnState
     * @return
     */
    private String qiNiuSwitch(String returnState) {
        String str;
        switch (returnState) {
            case Constants.StrStatusUtils.one:
                throw new BusinessException("QiniuException1:异常");
            case Constants.StrStatusUtils.two:
                throw new BusinessException("QiniuException2:异常");
            case Constants.StrStatusUtils.three:
                throw new BusinessException("IOException:异常");
                /*没有异常写入文件名路径*/
            default:
                str = returnState;
                break;
        }
        return str;
    }


}
